Force MultiThreaded execution mode and remove SingleThread option - #237
Merged
Conversation
SingleThread is incompatible with the Android Vulkan surface-readiness path (VeldridDevice polls SurfaceHandle for up to 5s on the same thread that publishes it in SingleThread mode -> deadlock -> null Vulkan func ptr -> SDLThread SI_TKILL crash within ~5s of launch, which matches the tablet crash report). The same pattern would also bite iOS Metal drawable attach. On desktop SingleThread is just slower with no UX benefit. Upstream ppy/osu defaults to MultiThreaded; we now enforce it on every startup so a stale framework.ini cannot pin a user into the broken mode. - OsuGameBase.load: force ExecutionMode = MultiThreaded once on load. - RendererSettings: drop the Threading Mode dropdown. - GraphicsSettingsStrings: drop the now-unused ThreadingMode string. - TestSceneOsuGame: drop TestSwitchThreadExecutionMode (covered behaviour is no longer user-reachable) and prune the now-unused usings. Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/cccaf70f-1049-4fde-a21c-cd61a27bf8b2 Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
Copilot created this pull request from a session on behalf of
winnerspiros
April 22, 2026 10:15
View session
- ci.yml: matrix.threadingMode reduced to ['MultiThreaded']. SingleThread is no longer a user-reachable mode (force-overridden in OsuGameBase), so testing under it just races the override and burns CI for an unsupported configuration. - README.md: drop the stale "Threading mode" row from the renderer options table; add a stability bullet documenting the MultiThreaded lock-in and the Android Vulkan-surface root cause. - No changes to runtime/src/test code beyond the previous PR; no optimizations are *unlocked* purely by the lock-in (Update / Draw / Audio / Input threads were already separate in MultiThreaded), so nothing else is touched. Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/89c57795-45d9-40ed-a99e-dd17caa8767d Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com>
winnerspiros
approved these changes
Apr 22, 2026
There was a problem hiding this comment.
Pull request overview
Locks the game/framework into multi-threaded execution by removing the user-facing SingleThread selection and ensuring stale config can’t persist a broken mode, while also reducing CI runtime by no longer testing an unreachable configuration.
Changes:
- Remove the Threading Mode (
ExecutionMode) dropdown from Graphics → Renderer settings and delete its localisation string. - Force
FrameworkSetting.ExecutionModetoExecutionMode.MultiThreadedon startup. - Remove the UI-path test and drop
SingleThreadfrom the CI test matrix; update README accordingly.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs | Removes the settings UI control for choosing execution mode. |
| osu.Game/OsuGameBase.cs | Forces MultiThreaded execution on startup to prevent persisted SingleThread usage. |
| osu.Game/Localisation/GraphicsSettingsStrings.cs | Removes the now-unused “Threading mode” localisation string. |
| osu.Game.Tests/Visual/Navigation/TestSceneOsuGame.cs | Removes a test that exercised switching execution modes via the removed UI/config path. |
| README.md | Updates documented renderer settings and adds a stability note explaining the lock-in rationale. |
| .github/workflows/ci.yml | Removes SingleThread from the CI test matrix to reduce runtime. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+332
to
+345
| // Force the framework execution mode to MultiThreaded on every startup. | ||
| // | ||
| // SingleThread used to be exposed in the graphics settings, but it is incompatible | ||
| // with our Android Vulkan-surface readiness path: VeldridDevice / AndroidGameHost | ||
| // poll AndroidGameWindow.SurfaceHandle for up to 5s, and in SingleThread mode that | ||
| // poll runs on the same thread that publishes the surface handle, deadlocking | ||
| // initialisation until the timeout fires and Vulkan device creation crashes with a | ||
| // null function pointer (see PR history around the SDLThread/SI_TKILL crash). | ||
| // | ||
| // The same risk applies to iOS Metal layer attach (drawable surfaces are also | ||
| // delivered via the main loop), and on desktop SingleThread is strictly slower with | ||
| // no UX benefit. Upstream ppy/osu defaults to MultiThreaded; we now enforce it | ||
| // unconditionally so a stale `framework.ini` cannot pin a user into the broken mode. | ||
| frameworkConfig.SetValue(FrameworkSetting.ExecutionMode, ExecutionMode.MultiThreaded); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ExecutionMode = MultiThreadedon game load inOsuGameBase(clears any persisted SingleThread value, all OSes)RendererSettingsThreadingModelocalisation stringTestSwitchThreadExecutionModetest that exercised the removed UI pathSingleThreadentry from the CI test matrix (no longer a user-reachable configuration; halves CI test time)Threading moderenderer option row; add stability bullet documenting the MultiThreaded lock-in and Android Vulkan-surface root causesingle-threaded executionworkaround comments inPlayButtonfiles remain harmless under MultiThreaded. Removing them would be a behaviour change with no clear win.